<template>
  <div
    class="setting-container"
    ref="settingMainRef"
    @scroll="handleScroll"
  >
    <div class="setting-tabs-wrap">
      <el-tabs
        v-model="activeName"
        class="setting-tabs t-tabs"
        tab-position="left"
        @tab-change="handleTabChange"
        ref="tabElRef"
      >
        <template
          v-for="tab in tabList"
          :key="tab.name"
        >
          <el-tab-pane
            v-if="isShowTab(tab.name)"
            :name="tab.name"
          >
            <template #label>
              <el-icon size="22">
                <component :is="tab.icon" />
              </el-icon>
              {{ tab.label }}
            </template>
          </el-tab-pane>
        </template>
      </el-tabs>
      <div
        class="content-wrap"
        :style="{ marginLeft: tabWidth + 'px' }"
      >
        <template
          v-for="tab in tabList"
          :key="tab.name"
        >
          <div
            v-if="isShowTab(tab.name)"
            :ref="(el: any) => (settingRefs[tab.name] = el)"
            :id="tab.name"
          >
            <component
              :is="tab.component"
              class="mt20"
              v-if="isVisible[tab.name]"
            />
          </div>
        </template>
        <!-- 添加底部空间，确保最后一个菜单可以正确选中 -->
        <div style="height: 200px;"></div>
      </div>
    </div>
  </div>
</template>

<script name="PublishTabs" setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref } from "vue";
import { useFormInfo } from "@/stores/formInfo";
import publicPublish from "./public.vue";
import PublicQuery from "./PublicQuery.vue";
import { loadAsyncComponent } from "@/utils/asyncComponent";
import { useDebounceFn, useElementSize } from "@vueuse/core";

import TablerLocationShare from "~icons/tabler/location-share";
import TablerListSearch from "~icons/tabler/list-search";
import TablerUserShare from "~icons/tabler/user-share";
import TablerTableShortcut from "~icons/tabler/table-shortcut";
import TablerDatabaseShare from "~icons/tabler/database-share";
import TablerMessage2Share from "~icons/tabler/message-2-share";
import TablerGift from "~icons/tabler/gift";
import TablerFileExport from "~icons/tabler/file-export";
import TablerFileCertificate from "~icons/tabler/file-certificate";
import TablerEyeTable from "~icons/tabler/eye-table";
import TablerUsersGroup from "~icons/tabler/users-group";
import TablerDeviceMobileCode from "~icons/tabler/device-mobile-code";
import { storeToRefs } from "pinia";
import { i18n } from "@/i18n";
import { useRoute } from "vue-router";

const AuthGroup = loadAsyncComponent(() => import("./AuthGroup.vue"));
const TodoTaskForm = loadAsyncComponent(() => import("./TodoForm/index.vue"));
const TargetedPublish = loadAsyncComponent(() => import("./TargetedPublish.vue"));
const DataPush = loadAsyncComponent(() => import("./DataPush.vue"));
const DataHelper = loadAsyncComponent(() => import("./DataHelper/index.vue"));
const NotifyShare = loadAsyncComponent(() => import("./NotifyShare/index.vue"));
const PrintTemplate = loadAsyncComponent(() => import("./PrintTemplate/index.vue"));
const CertificateGen = loadAsyncComponent(() => import("./CertificateGen/index.vue"));
const FormLottery = loadAsyncComponent(() => import("./Lottery/index.vue"));
const FormEmbed = loadAsyncComponent(() => import("./FormEmbed/index.vue"));

const activeName = ref("publicPublish");

const formInfoStore = useFormInfo();

const { hasFormButtonAuth } = formInfoStore;

const { formType, formButtonAuths } = storeToRefs(formInfoStore);

const settingRefs = ref<any>({});

const tabElRef = ref(null);
const { width: tabWidth } = useElementSize(tabElRef);

const handleTabChange = (name: string) => {
  nextTick(() => {
    smoothScroll(settingRefs.value[name]);
  });
};

function smoothScroll(element: HTMLElement, duration: number = 500) {
  console.log(element);
  const targetPosition = element.offsetTop - 40;
  const startPosition = element.scrollTop;
  console.log(startPosition);
  console.log(targetPosition);
  const distance = targetPosition - startPosition;
  let start: number | null = null;

  const easeInOutQuad = (t: number): number => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t);

  function step(timestamp: number) {
    if (!start) start = timestamp;
    const progress = timestamp - start;
    const ease = easeInOutQuad(progress / duration);
    settingMainRef.value!.scrollTop = startPosition + distance * ease;
    if (progress < duration) {
      window.requestAnimationFrame(step);
    }
  }

  window.requestAnimationFrame(step);
}

const settingMainRef = ref<HTMLDivElement | null>(null);

// 初始化每个元素的可见性状态
const isVisible = ref<any>({});

const tabList = [
  {
    name: "publicPublish",
    label: i18n.global.t("form.leftTab.publicRelease"),
    component: publicPublish,
    icon: TablerLocationShare
  },
  {
    name: "targetedPublish",
    label: i18n.global.t("form.leftTab.specifyFill"),
    component: TargetedPublish,
    icon: TablerUserShare
  },
  {
    name: "dataHelper",
    label: i18n.global.t("form.leftTab.dataAssistant"),
    component: DataHelper,
    icon: TablerEyeTable
  },
  {
    name: "publicQuery",
    label: i18n.global.t("form.leftTab.publicQuery"),
    component: PublicQuery,
    icon: TablerListSearch
  },
  {
    name: "fillTask",
    label: i18n.global.t("form.leftTab.fillTask"),
    component: TodoTaskForm,
    icon: TablerUsersGroup
  },
  // TODO: 抽离抽奖功能 @chd
  // {
  //   name: "lottery",
  //   label: i18n.global.t("form.leftTab.lottery"),
  //   component: FormLottery,
  //   icon: TablerGift
  // },
  {
    name: "notifyShare",
    label: i18n.global.t("form.leftTab.notifyShare"),
    component: NotifyShare,
    icon: TablerMessage2Share
  },
  {
    name: "authGroup",
    label: i18n.global.t("form.leftTab.dataView"),
    component: AuthGroup,
    icon: TablerTableShortcut
  },
  {
    name: "dataPush",
    label: i18n.global.t("form.leftTab.dataPush"),
    component: DataPush,
    icon: TablerDatabaseShare
  },
  {
    name: "printTemplate",
    label: i18n.global.t("form.leftTab.printTemplate"),
    component: PrintTemplate,
    icon: TablerFileExport
  },
  {
    name: "certificateGen",
    label: i18n.global.t("form.leftTab.certificateGen"),
    component: CertificateGen,
    icon: TablerFileCertificate
  },
  {
    name: "embed",
    label: i18n.global.t("form.leftTab.embed"),
    component: FormEmbed,
    icon: TablerDeviceMobileCode
  }
];

const isShowTab = (name: string) => {
  if (name === "publicPublish" && formType.value === 6) {
    return false;
  }
  return hasFormButtonAuth(name);
};

const route = useRoute();

onMounted(() => {
  // 加载字段
  formInfoStore.loadFormFields(route.query.key as string);
  // 如果没有公开发布的权限
  if (!hasFormButtonAuth("publicPublish") && formButtonAuths.value && formButtonAuths.value.length > 0) {
    const tabName = formButtonAuths.value.filter((item: any) => tabList.includes(item))[0];
    activeName.value = tabName;
    nextTick(() => {
      handleTabChange(tabName);
    });
  }
});

let observer: IntersectionObserver;

const handleIntersection = (entries: any[]) => {
  entries.forEach((entry: any) => {
    if (entry.isIntersecting) {
      console.log(entry.target.id);
      isVisible.value[entry.target.id] = true;
      // 元素可见后取消观察
      observer.unobserve(entry.target);
    }
  });
};

onMounted(() => {
  nextTick(() => {
    observer = new IntersectionObserver(handleIntersection);
    console.log(settingRefs.value);
    for (const id in settingRefs.value) {
      const el = settingRefs.value[id];
      // 判断el是不是一个dom
      if (el instanceof HTMLElement) {
        // 判断是不是一个dom
        observer.observe(el);
      }
    }
  });
});

onUnmounted(() => {
  if (observer) {
    observer.disconnect();
  }
});

const getCurrentScrollDom = () => {
  const current = settingMainRef.value!.scrollTop + 20; // 获取当前滚动条离顶部高度
  let currentTab = "";
  let maxTop = 0;
  for (let key of Object.keys(settingRefs.value)) {
    const top = settingRefs.value[key].offsetTop;
    if (current + 200 > top && top > maxTop) {
      currentTab = key;
      maxTop = top;
    }
  }
  return currentTab;
};

const handleScroll = useDebounceFn(() => {
  activeName.value = getCurrentScrollDom();
}, 300);
</script>

<style lang="scss" scoped>
.setting-container {
  height: calc(100vh - 46px);
  background-color: var(--el-bg-color-page);
  overflow: auto;
  position: relative;
  z-index: 10;
  width: 100%;

  .setting-tabs-wrap {
    margin: 0 auto;
    width: 980px;
  }

  .setting-tabs {
    border-radius: 8px;
    margin-top: 20px;
    min-height: 500px;
    position: fixed;
    top: 66px;
    z-index: 10;
    --el-color-primary-light-9: var(--el-color-primary);
    :deep(.el-tabs__item.is-active) {
      color: var(--el-bg-color-overlay);
    }
  }
  .content-wrap {
    width: 780px;
    padding-top: 20px;
    padding-bottom: 100px;
  }
}
:deep(.el-tabs__item) {
  justify-content: left !important;
}

:deep(.el-card) {
  border: none;
  border-radius: 7px;
  .el-card__header {
    padding: 10px;
    color: var(--el-text-color-primary);
    font-size: 16px;
    text-align: left;
    font-weight: 500;
    margin-left: 20px;
    line-height: 40px;
  }
}
</style>
